package com.kadron.datamodel;

import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.faces.context.FacesContext;

import org.ajax4jsf.model.DataVisitor;
import org.ajax4jsf.model.ExtendedDataModel;
import org.ajax4jsf.model.Range;
import org.ajax4jsf.model.SequenceRange;

public class KDataModel extends ExtendedDataModel implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = -6929477453431395795L;
	
	private Long id; 
	private KDataProvider dataProvider;
	private Map<Long,KModel> wrappedData = new HashMap<Long,KModel>();
    private List<Long> wrappedKeys = null;
	
    private Integer rowCount;
    
	public KDataModel(KDataProvider dataProvider) {
		super();
		this.dataProvider = dataProvider;
	}

	@Override
	public Object getRowKey() {
		return id;
	}

	@Override
	public void setRowKey(Object arg0) {
		this.id = (Long) arg0;
	}

	@Override
	public void walk(FacesContext context, DataVisitor visitor, Range range, Object argument) throws IOException {
		int firstRow = ((SequenceRange)range).getFirstRow();
        int numberOfRows = ((SequenceRange)range).getRows();
        wrappedKeys = new ArrayList<Long>();
        for (Long itemId : dataProvider.getItemsByRange(new Integer(firstRow), numberOfRows, null, true)) {
            wrappedKeys.add(itemId);
            KModel model = dataProvider.getItemById(itemId, dataProvider.getCreator());
            wrappedData.put(itemId, model);
            visitor.process(context, model.getId(), argument);
        }
	}

	@Override
	public int getRowCount() {
		if(rowCount==null) {
            rowCount = new Integer(dataProvider.getRowCount());
            return rowCount.intValue();
        } else {
            return rowCount.intValue();
        }
	}

	@Override
	public Object getRowData() {
		if (id == null) {
            return null;
        } else {
            KModel model = (KModel) wrappedData.get(id);
            if (model==null) {
                model = dataProvider.getItemById(id,dataProvider.getCreator());
                wrappedData.put(id, model);
                return model;
            } else {
                return model;
            }
        }
	}

	@Override
	public int getRowIndex() {
		throw new UnsupportedOperationException("Called getRowIndex() ");
	}

	@Override
	public Object getWrappedData() {
		return wrappedData;
	}

	@Override
	public boolean isRowAvailable() {
		if (id == null) {
			return false;
		}
		if (wrappedData.containsKey(id)) {
			return true;
		} else {
			return dataProvider.hasItemWithId(id);
		}
	}

	@Override
	public void setRowIndex(int arg0) {
		throw new UnsupportedOperationException("Called setRowIndex(int arg0) ");
	}

	@Override
	public void setWrappedData(Object arg0) {
		throw new UnsupportedOperationException("Called setWrappedData(Object arg0)");
	}
	
	public Collection<KModel> getList() {
		return wrappedData.values();
	}
	
	public void remove(KModel model) {
		wrappedData.remove(model);
		wrappedKeys.remove(model.getId());
	}
	
	public void removeAll(Collection<Long> ids) {
		wrappedData.keySet().removeAll(ids);
		wrappedKeys.removeAll(ids);
	}
	
}
